home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / sail.tar / sail / dr_3.c < prev    next >
C/C++ Source or Header  |  1992-09-18  |  7KB  |  326 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)dr_3.c    5.2 (Berkeley) 3/9/88";
  15. #endif /* not lint */
  16.  
  17. #include "driver.h"
  18.  
  19. moveall()        /* move all comp ships */
  20. {
  21.     register struct ship *sp, *sq;        /* r11, r10 */
  22.     register int n;                /* r9 */
  23.     register int k, l;            /* r8, r7 */
  24.     int row[NSHIP], col[NSHIP], dir[NSHIP], drift[NSHIP];
  25.     char moved[NSHIP];
  26.  
  27.     /*
  28.      * first try to create moves for OUR ships
  29.      */
  30.     foreachship(sp) {
  31.         struct ship *closest;
  32.         int ma, ta;
  33.         char af;
  34.  
  35.         if (sp->file->captain[0] || sp->file->dir == 0)
  36.             continue;
  37.         if (!sp->file->struck && windspeed && !snagged(sp)
  38.             && sp->specs->crew3) {
  39.             ta = maxturns(sp, &af);
  40.             ma = maxmove(sp, sp->file->dir, 0);
  41.             closest = closestenemy(sp, 0, 0);
  42.             if (closest == 0)
  43.                 *sp->file->movebuf = '\0';
  44.             else
  45.                 closeon(sp, closest, sp->file->movebuf,
  46.                     ta, ma, af);
  47.         } else
  48.             *sp->file->movebuf = '\0';
  49.     }
  50.     /*
  51.      * Then execute the moves for ALL ships (dead ones too),
  52.      * checking for collisions and snags at each step.
  53.      * The old positions are saved in row[], col[], dir[].
  54.      * At the end, we compare and write out the changes.
  55.      */
  56.     n = 0;
  57.     foreachship(sp) {
  58.         if (snagged(sp))
  59.             (void) strcpy(sp->file->movebuf, "d");
  60.         else
  61.             if (*sp->file->movebuf != 'd')
  62.                 (void) strcat(sp->file->movebuf, "d");
  63.         row[n] = sp->file->row;
  64.         col[n] = sp->file->col;
  65.         dir[n] = sp->file->dir;
  66.         drift[n] = sp->file->drift;
  67.         moved[n] = 0;
  68.         n++;
  69.     }
  70.     /*
  71.      * Now resolve collisions.
  72.      * This is the tough part.
  73.      */
  74.     for (k = 0; stillmoving(k); k++) {
  75.         /*
  76.          * Step once.
  77.          * And propagate the nulls at the end of sp->file->movebuf.
  78.          */
  79.         n = 0;
  80.         foreachship(sp) {
  81.             if (!sp->file->movebuf[k])
  82.                 sp->file->movebuf[k+1] = '\0';
  83.             else if (sp->file->dir)
  84.                 step(sp->file->movebuf[k], sp, &moved[n]);
  85.             n++;
  86.         }
  87.         /*
  88.          * The real stuff.
  89.          */
  90.         n = 0;
  91.         foreachship(sp) {
  92.             if (sp->file->dir == 0 || isolated(sp))
  93.                 goto cont1;
  94.             l = 0;
  95.             foreachship(sq) {
  96.                 char snap = 0;
  97.  
  98.                 if (sp == sq)
  99.                     goto cont2;
  100.                 if (sq->file->dir == 0)
  101.                     goto cont2;
  102.                 if (!push(sp, sq))
  103.                     goto cont2;
  104.                 if (snagged2(sp, sq) && range(sp, sq) > 1)
  105.                     snap++;
  106.                 if (!range(sp, sq) && !fouled2(sp, sq)) {
  107.                     makesignal(sp,
  108.                         "collision with %s (%c%c)", sq);
  109.                     if (die() < 4) {
  110.                         makesignal(sp,
  111.                             "fouled with %s (%c%c)",
  112.                             sq);
  113.                         Write(W_FOUL, sp, 0, l, 0, 0, 0);
  114.                         Write(W_FOUL, sq, 0, n, 0, 0, 0);
  115.                     }
  116.                     snap++;
  117.                 }
  118.                 if (snap) {
  119.                     sp->file->movebuf[k + 1] = 0;
  120.                     sq->file->movebuf[k + 1] = 0;
  121.                     sq->file->row = sp->file->row - 1;
  122.                     if (sp->file->dir == 1
  123.                         || sp->file->dir == 5)
  124.                         sq->file->col =
  125.                             sp->file->col - 1;
  126.                     else
  127.                         sq->file->col = sp->file->col;
  128.                     sq->file->dir = sp->file->dir;
  129.                 }
  130.             cont2:
  131.                 l++;
  132.             }
  133.         cont1:
  134.             n++;
  135.         }
  136.     }
  137.     /*
  138.      * Clear old moves.  And write out new pos.
  139.      */
  140.     n = 0;
  141.     foreachship(sp) {
  142.         if (sp->file->dir != 0) {
  143.             *sp->file->movebuf = 0;
  144.             if (row[n] != sp->file->row)
  145.                 Write(W_ROW, sp, 0, sp->file->row, 0, 0, 0);
  146.             if (col[n] != sp->file->col)
  147.                 Write(W_COL, sp, 0, sp->file->col, 0, 0, 0);
  148.             if (dir[n] != sp->file->dir)
  149.                 Write(W_DIR, sp, 0, sp->file->dir, 0, 0, 0);
  150.             if (drift[n] != sp->file->drift)
  151.                 Write(W_DRIFT, sp, 0, sp->file->drift, 0, 0, 0);
  152.         }
  153.         n++;
  154.     }
  155. }
  156.  
  157. stillmoving(k)
  158. register int k;
  159. {
  160.     register struct ship *sp;
  161.  
  162.     foreachship(sp)
  163.         if (sp->file->movebuf[k])
  164.             return 1;
  165.     return 0;
  166. }
  167.  
  168. isolated(ship)
  169. register struct ship *ship;
  170. {
  171.     register struct ship *sp;
  172.  
  173.     foreachship(sp) {
  174.         if (ship != sp && range(ship, sp) <= 10)
  175.             return 0;
  176.     }
  177.     return 1;
  178. }
  179.  
  180. push(from, to)
  181. register struct ship *from, *to;
  182. {
  183.     register int bs, sb;
  184.  
  185.     sb = to->specs->guns;
  186.     bs = from->specs->guns;
  187.     if (sb > bs)
  188.         return 1;
  189.     if (sb < bs)
  190.         return 0;
  191.     return from < to;
  192. }
  193.  
  194. step(com, sp, moved)
  195. char com;
  196. register struct ship *sp;
  197. char *moved;
  198. {
  199.     register int dist;
  200.  
  201.     switch (com) {
  202.     case 'r':
  203.         if (++sp->file->dir == 9)
  204.             sp->file->dir = 1;
  205.         break;
  206.     case 'l':
  207.         if (--sp->file->dir == 0)
  208.             sp->file->dir = 8;
  209.         break;
  210.         case '0': case '1': case '2': case '3':
  211.         case '4': case '5': case '6': case '7':
  212.         if (sp->file->dir % 2 == 0)
  213.             dist = dtab[com - '0'];
  214.         else
  215.             dist = com - '0';
  216.         sp->file->row -= dr[sp->file->dir] * dist;
  217.         sp->file->col -= dc[sp->file->dir] * dist;
  218.         *moved = 1;
  219.         break;
  220.     case 'b':
  221.         break;
  222.     case 'd':
  223.         if (!*moved) {
  224.             if (windspeed != 0 && ++sp->file->drift > 2 &&
  225.                 (sp->specs->class >= 3 && !snagged(sp)
  226.                  || (turn & 1) == 0)) {
  227.                 sp->file->row -= dr[winddir];
  228.                 sp->file->col -= dc[winddir];
  229.             }
  230.         } else
  231.             sp->file->drift = 0;
  232.         break;
  233.     }
  234. }
  235.  
  236. sendbp(from, to, sections, isdefense)
  237. register struct ship *from, *to;
  238. int sections;
  239. char isdefense;
  240. {
  241.     int n;
  242.     register struct BP *bp;
  243.  
  244.     bp = isdefense ? from->file->DBP : from->file->OBP;
  245.     for (n = 0; n < NBP && bp[n].turnsent; n++)
  246.         ;
  247.     if (n < NBP && sections) {
  248.         Write(isdefense ? W_DBP : W_OBP, from, 0,
  249.             n, turn, to->file->index, sections);
  250.         if (isdefense)
  251.             makesignal(from, "repelling boarders",
  252.                 (struct ship *)0);
  253.         else
  254.             makesignal(from, "boarding the %s (%c%c)", to);
  255.     }
  256. }
  257.  
  258. toughmelee(ship, to, isdefense, count)
  259. register struct ship *ship, *to;
  260. int isdefense, count;
  261. {
  262.     register struct BP *bp;
  263.     register obp = 0;
  264.     int n, OBP = 0, DBP = 0, dbp = 0;
  265.     int qual;
  266.  
  267.     qual = ship->specs->qual;
  268.     bp = isdefense ? ship->file->DBP : ship->file->OBP;
  269.     for (n = 0; n < NBP; n++, bp++) {
  270.         if (bp->turnsent && (to == bp->toship || isdefense)) {
  271.             obp += bp->mensent / 100
  272.                 ? ship->specs->crew1 * qual : 0;
  273.             obp += (bp->mensent % 100)/10
  274.                 ? ship->specs->crew2 * qual : 0;
  275.             obp += bp->mensent % 10
  276.                 ? ship->specs->crew3 * qual : 0;
  277.         }
  278.     }
  279.     if (count || isdefense)
  280.         return obp;
  281.     OBP = toughmelee(to, ship, 0, count + 1);
  282.     dbp = toughmelee(ship, to, 1, count + 1);
  283.     DBP = toughmelee(to, ship, 1, count + 1);
  284.     if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
  285.         return 1;
  286.     else
  287.         return 0;
  288. }
  289.  
  290. reload()
  291. {
  292.     register struct ship *sp;
  293.  
  294.     foreachship(sp) {
  295.         sp->file->loadwith = 0;
  296.     }
  297. }
  298.  
  299. checksails()
  300. {
  301.     register struct ship *sp;
  302.     register int rig, full; 
  303.     struct ship *close;
  304.  
  305.     foreachship(sp) {
  306.         if (sp->file->captain[0] != 0)
  307.             continue;
  308.         rig = sp->specs->rig1;
  309.         if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
  310.             rig = 0;
  311.         if (rig && sp->specs->crew3) {
  312.             close = closestenemy(sp, 0, 0);
  313.             if (close != 0) {
  314.                 if (range(sp, close) > 9)
  315.                     full = 1;
  316.                 else
  317.                     full = 0;
  318.             } else 
  319.                 full = 0;
  320.         } else
  321.             full = 0;
  322.         if ((sp->file->FS != 0) != full)
  323.             Write(W_FS, sp, 0, full, 0, 0, 0);
  324.     }
  325. }
  326.